/**
 * @addtogroup list.h
 * list.h
 * @{
 */
/**
 * @file         ofc_list.h
 * @brief        List队列
 * @note         使用时请注意：所有接口内部不判断对象参数的有效性，需要外部自己判断；多线程不安全，可重入;创建列表使用后,注意内存的释放，使用之前需要实现设置OfSetMallocProc和OfSetFreeProc的函数.
 * @author       Leo
 * @date         2020-08-18
 * @version      1.4
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2018-11-16  <td>1.0                   <td>Leo             <td>创建初始版本
 * <tr><td>2019-09-18  <td>1.1                   <td>Akee            <td>由C++版本转换为C版本
 * <tr><td>2019-11-13  <td>1.2                   <td>Leo             <td>rfc转换为ofc,并作部分修改
 * <tr><td>2019-12-19  <td>1.3                   <td>Akee            <td>修复Insert和Delete时,memmove的src和dst参数错误
  * <tr><td>2020-08-18 <td>1.4                   <td>Leo             <td>增加TOfListSetItem和TOfListDelete的返回值类型Bool,原先为void
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _OFC_LIST_H_ 
#define _OFC_LIST_H_

#include "ofc_object.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct TOfListTag TOfList;

/**
 * 比较排序方法
 * @note 若在TOfListQuickfind中使用，item1为TOfList容器中的对象，item2为TOfListQuickFind函数的第二个参数（item）
 * @param item1: 指针对象（使用TOfListQuickFind时:TOfList容器中的项）
 * @param item2: 指针对象（使用TOfListQuickFind时:TOfListQuickFind函数的第二个参数）
 * @return 返回值大于0: item1>item2 返回值等于0:item1==item2 返回值小于0: item1<item2
 */
typedef long (*TOfListSortCompare)(void *item1, void *item2);

/**
 * 删除通知事件
 * @param sender: 事件发起者
 * @param ptr: 删除内存指针
 * @return 无返回值
 */
typedef void (*TOfListOnDelete)(TOfList *sender, void *ptr);

/**
 * 列表
 */
struct TOfListTag 
{
PROTECTED
    TOfObject parent_;  ///< 基类
    TOfVirtualMethod Destroy_;  ///< 析构事件

PUBLIC
    TOfListOnDelete OnDelete;  ///< 删除事件
    void *receiver;  ///< 可以存放事件的接收者

PRIVATE
    Int32 capacity_;  ///< 容量
    void **list_;  ///< 数据
    Int32 count_;  ///< 个数
};

/**
 * TOfList构造
 * @param self: 对象指针
 * @return 无返回值
 * @par 示例
 * @code
 *    TOfList list；// list为列表名
 
 *    TOfListCreate(&list);
 *    .......
 *    OfDestroyObject((TOfObject *)&list);
 * @endcode
 * @note 若采用此方法创建对象,需采用[OfDestroyObject](@ref OfDestroyObject)函数销毁对象
 */
void TOfListCreate(TOfList *self);

/**
 * 创建一个列表
 * @return 返回创建的对象,创建失败返回NULL
 * @par 示例
 * @code
 *    OfSetMallocProc(malloc);
 *    OfSetFreeProc(free);
 
 *    TOfList *list = OfCreateList()；// list为列表名
 *    ......
 *    OfFreeObject((TOfObject *)list);
 * @endcode
 * @note 
 *    - 创建一个新列表之前,若没有执行[OfSetMallocProc](@ref OfSetMallocProc),则列表会创建失败,无法分配空间.详细请参见[OfSetMallocProc](@ref OfSetMallocProc)
 *    - 若采用此方法创建对象,需采用[OfFreeObject](@ref OfFreeObject)函数释放内存.详细请参见[OfFreeObject](@ref OfFreeObject)
 */
TOfList *OfCreateList(void);

/**
 * 增加一项到队列末尾
 * @param self: 对象指针
 * @param item: 增加的内容
 * @return 增加到所对应的索引,参数错误和增加失败返回(-1)
 */
Int32 TOfListAdd(TOfList *self, void *item);

/**
 * 获取队列中的一项的数据
 * @param self: 对象指针
 * @param index: 获取的索引
 * @return 返回索引所在的内容,参数错误返回NULL
 */
void *TOfListItems(TOfList *self, Int32 index);

/**
 * 设置某一项的数据,删除原数据时,内部会自动调用OnDelete事件
 * @param self: 对象指针
 * @param index: 设置的索引
 * @param item: 设置的内容
 * @return 设置成功返回True,否则返回False.失败的原因是index不在列表范围内.
 */
Bool TOfListSetItem(TOfList *self, Int32 index, void *item);

/**
 * 清除队列数据,删除时会依次调用OnDelete事件
 * @param self: 对象指针
 * @return 无返回值
 */
void TOfListClear(TOfList *self);

/**
 * 删除某一项,内部自动调用OnDelete事件
 * @param self: 对象指针
 * @param index: 删除的索引
 * @return 删除成功返回True,否则返回False,失败的原因为index不在列表范围内.
 */
Bool TOfListDelete(TOfList *self, Int32 index);

/**
 * 通过指针获取队列内部是否存在所对应的数据
 * @param self: 对象指针
 * @param item: 数据的地址
 * @return 返回数据所在的索引,参数错误和数据不存在时返回(-1)
 */
Int32 TOfListIndexOf(TOfList *self, void *item);

/**
 * 插入一项数据到队列
 * @param self: 对象指针
 * @param index: 插入的索引
 * @param item: 插入的数据
 * @return 插入成功返回True,否则返回False
 */
Bool TOfListInsert(TOfList *self, Int32 index, void *item);

/**
 * 删除某一项数据,内部自动调用OnDelete事件
 * @param self: 对象指针
 * @param item: 删除的数据
 * @return 删除所在的索引，若不存在则返回(-1)
 */
Int32 TOfListRemove(TOfList *self, void *item);

/**
 * 获取队列个数
 * @param self: 对象指针
 * @return 返回获得的个数
 */
Int32 TOfListCount(TOfList *self);

/**
 * 设置队列的个数
 * @param self: 对象指针
 * @param new_count: 个数
 * @return 设置成功返回True,设置失败返回False
 */
Bool TOfListSetCount(TOfList *self, Int32 new_count);

/**
 * 列表排序
 * @note 内部会递归，小内存平台慎用，递归深度跟内部对象个数有关系
 * @param self: 对象指针
 * @param compare: 排序方法
 * @return 无返回值
 */
 
void TOfListSort(TOfList *self, TOfListSortCompare compare);
/**
 * 通过快速查找方法找到所对应的索引，需要先排序好后再查找
 * @param self: 对象指针
 * @param item: 所要查找的数据
 * @param compare: 查找时所用的方法
 * @param index: 返回索引(可定义一个变量,将该变量的地址传入函数,函数执行后会将索引值存储在该变量中)
 * @return 
 *    - item在列表中找到则返回True,index为索引值
 *    - 如未找到则返回False,index为可插入的索引,按照index插入查询的数据,列表依旧按照一定顺序排列.
 * @note compare与index不能为NULL
 */
Bool TOfListQuickFind(TOfList *self, void *item, TOfListSortCompare compare, Int32 *index);

/**
 * 删除列表中从index开始的count项.
 * 删除的项如果不为NULL会调用OnDelete函数
 * @param self: 对象指针
 * @param index: 要删除的第一项的索引; 如果index<0,则从第一项开始删除.如果index >= TOfListCount()则不删除
 * @param count: 要删除的项数.超出范围的项不会被删除
 * @return 无返回值
 */
void TOfListDeleteEx(TOfList *self, Int32 index, Int32 count);

/**
 * 获取列表中的容量
 * @param self: 对象指针
 * @return 容量大小
 */
Int32 TOfListCapacity(TOfList *self);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif //_OFC_LIST_H_

/**
 * @}
 */
